In info.plist

Note: in the Plist editor LSUIElement shows up as "Application is Agent" (LSUIElement) otherwise look for it in the info.plist file using a text editor searching for LSUIElement

The following makes it so no app icon appears in the Dock, no menus in the menu bar, and now windows
	<key>LSBackgroundOnly</key>
	<true/>
The following makes it so no app icon appears in the Dock and no menus in the menu bar but you can still display a window
	<key>LSUIElement</key>
	<true/>

When you have LSUIElement you need the following in the info.plist, otherwise it won't run:

	<key>NSMainNibFile</key>
	<string>MainMenu</string>


================
	//[deviceMenuItem setImage:[[NSWorkspace sharedWorkspace]iconForFile:[[NSBundle mainBundle] pathForResource:@"WDDriveManagerStatusMenu" ofType:@"icns"]]];
================ searching volumnes
/* After the application finishes launching, we search for mounted volumes that
might be DVD media. We attempt to open each volume for playback. We can open
only one media folder at a time, so we stop when we succeed. */

- (BOOL) searchMountedDVDDisc
{
  BOOL foundDVD = NO;

  /* get an array of strings containing the full pathnames of all
  currently mounted removable media */
  NSArray *volumes = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];

  int i, count = [volumes count];
  for (i = 0; i < count; i++)
  {
    /* get the next volume path, and append the standard name for the
    media folder on a DVD-Video volume */
    NSString *path = [[volumes objectAtIndex:i] stringByAppendingString:@"/VIDEO_TS"];

    foundDVD = [self openMedia:path isVolume:YES];

    if (foundDVD) {
      /* we just opened a DVD volume */
      break;
    }
  }

  return foundDVD;
}
=====================

//
//  main.m
//  StatusMenu
//
//  Created by Clark Jackson on 10/6/08.
//  Copyright __MyCompanyName__ 2008. All rights reserved.
//


#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <errno.h>
#include <string.h>
#include <inttypes.h>

#define NUM_EVENT_SLOTS 1
#define NUM_EVENT_FDS 1

// global variables
extern int kq

char *flagstring(int flags);

void *doKernelQueue(char *pathOfFileToMonitor)
{
	int g_kq;
	int event_fd;
	struct kevent events_to_monitor[NUM_EVENT_FDS];
	struct kevent event_data[NUM_EVENT_SLOTS];
	void *user_data;
	struct timespec timeout;
	unsigned int vnode_events;
	
	fprintf(stderr, "got to doKernelQueue\n");

	
	if (strlen(pathOfFileToMonitor)==0)
	{
		fprintf(stderr, "doKernelQueue: path of length error\n");
		exit(-1);
	}
	
	/* Open a kernel queue. */
	if ((kq = kqueue()) < 0)
	{
		fprintf(stderr, "Could not open kernel queue.  Error was %s.\n", strerror(errno));
	}
	
	/*
	 Open a file descriptor for the file/directory that you
	 want to monitor.
	 */
	event_fd = open(pathOfFileToMonitor, O_EVTONLY);
	if (event_fd <=0)
	{
		fprintf(stderr, "The file %s could not be opened for monitoring.  Error was %s.\n", pathOfFileToMonitor, strerror(errno));
		exit(-1);
	}
	
	/*
	 The address in user_data will be copied into a field in the
	 event.  If you are monitoring multiple files, you could,
	 for example, pass in different data structure for each file.
	 For this example, the pathOfFileToMonitor string is used.
	 */
	user_data = pathOfFileToMonitor;
	
	/* Set the timeout to wake us every 3 seconds. */
	timeout.tv_sec = 3;        // 3 seconds
	timeout.tv_nsec = 0;    // 0 microseconds
	
	/* Set up a list of events to monitor. */
	//vnode_events = NOTE_DELETE |  NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE;
	vnode_events = NOTE_DELETE | NOTE_WRITE | NOTE_RENAME;
	EV_SET( &events_to_monitor[0], event_fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, vnode_events, 0, user_data);
	
	/* Handle events. */
	int num_files = 1;
	//int continue_loop = 40; /* Monitor for twenty seconds. */
	int continue_loop = 2; /* just do it once, timeout will be 3 seconds. */
//	while (--continue_loop)
	while (--continue_loop) // loop once 
	{
		fprintf(stderr, "got to doKernelQueue inside loop\n");
		int event_count = kevent(kq, events_to_monitor, NUM_EVENT_SLOTS, event_data, num_files, &timeout);
		//int event_count = kevent(kq, events_to_monitor, NUM_EVENT_SLOTS, event_data, num_files, NULL);
		if ((event_count < 0) || (event_data[0].flags == EV_ERROR)) {
			/* An error occurred. */
			fprintf(stderr, "An error occurred (event count %d).  The error was %s.\n", event_count, strerror(errno));
			break;
		}
		if (event_count) {
			printf("Event %" PRIdPTR " occurred.  Filter %d, flags %d, filter flags %s, filter data %" PRIdPTR ", pathOfFileToMonitor %s\n",
				   event_data[0].ident,
				   event_data[0].filter,
				   event_data[0].flags,
				   flagstring(event_data[0].fflags),
				   event_data[0].data,
				   (char *)event_data[0].udata);
		} else {
			printf("No event.\n");
		}
		
		/* Reset the timeout.  In case of a signal interrruption, the
		 values may change. */
		timeout.tv_sec = 3;        // 0 seconds
		timeout.tv_nsec = 0;    // 500 microseconds
	}
	close(event_fd);
	return 0;
}

/* A simple routine to return a string for a set of flags. */
char *flagstring(int flags)
{
    static char ret[512];
    char *or = "";
	
    ret[0]='\0'; // clear the string.
    if (flags & NOTE_DELETE) {strcat(ret,or);strcat(ret,"NOTE_DELETE");or="|";}
    if (flags & NOTE_WRITE) {strcat(ret,or);strcat(ret,"NOTE_WRITE");or="|";}
    if (flags & NOTE_EXTEND) {strcat(ret,or);strcat(ret,"NOTE_EXTEND");or="|";}
    if (flags & NOTE_ATTRIB) {strcat(ret,or);strcat(ret,"NOTE_ATTRIB");or="|";}
    if (flags & NOTE_LINK) {strcat(ret,or);strcat(ret,"NOTE_LINK");or="|";}
    if (flags & NOTE_RENAME) {strcat(ret,or);strcat(ret,"NOTE_RENAME");or="|";}
    if (flags & NOTE_REVOKE) {strcat(ret,or);strcat(ret,"NOTE_REVOKE");or="|";}
	
    return ret;
}



#import <Cocoa/Cocoa.h>

int main(int argc, char *argv[])
{
    return NSApplicationMain(argc,  (const char **) argv);
}
